package priv.happy.mealpickpro.interceptor;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import priv.happy.mealpickpro.util.InterceptUtil;
import priv.happy.mealpickpro.util.JWTUtil;
import priv.happy.mealpickpro.vo.ApiResponse;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;

/**
 * @Author: HAPPY
 * @Project_name: recruitSystem
 * @Package_name: grad.nxu.recruitsystem.interceptor
 * @Date: 2023/3/10 9:54
 * @Description:
 */

@Component
public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        ApiResponse<String> apiResponse = new ApiResponse<>();
        // 获取客户端请求头里的token
        String requestToken = request.getHeader("token");
        // 如果没有token，直接返回失败
        if (requestToken == null) {
            String jsonObjectStr = JSONObject.toJSONString(apiResponse.setCode(403).setMessage("请登录后再使用此网站").setSuccess(false));
            InterceptUtil.returnJson(response, jsonObjectStr);
            return false;
        }
        // 验证请求头里的token是否有效
        if (JWTUtil.validateToken(requestToken)) {
            String email = (String) JWTUtil.getPayload(requestToken, "email");
            // 获取缓存里的token
            String redisToken = stringRedisTemplate.opsForValue().get("mealpickpro:token:" + email);
            // 判断二者是否一致，防止请求头里携带的是从别的地方获取到的他人有效token
            if (requestToken.equals(redisToken)) {
                // 权限验证
                String role = (String) JWTUtil.getPayload(requestToken, "role");
                if (!"管理员".equals(role) && request.getRequestURI().contains("admin")) {
                    String jsonObjectStr = JSONObject.toJSONString(apiResponse.setCode(403).setMessage("当前用户无该访问权限,请登录管理员账号").setSuccess(false));
                    InterceptUtil.returnJson(response, jsonObjectStr);
                    return false;
                }
                // 如果token有效期少于一天，刷新token有效期
                Long expire = stringRedisTemplate.getExpire("mealpickpro:token:" + email);
                if (expire != null && expire < 60 * 60 * 24)
                    stringRedisTemplate.opsForValue().set("mealpickpro:token:" + email, requestToken, Duration.ofDays(7));
                return true;
            }
        }
        String jsonObjectStr = JSONObject.toJSONString(apiResponse.setCode(403).setMessage("登录状态失效，请重新登录！").setSuccess(false));
        InterceptUtil.returnJson(response, jsonObjectStr);
        return false;
    }
}